﻿using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.Mvc;
using WebStickyNotes.Contracts;
using WebStickyNotes.Contracts.Interfaces;
using WebStickyNotes.Data.Access;
using WebStickyNotes.Helpers;
using WebStickyNotes.Models;
using WebStickyNotes.Resources;

namespace WebStickyNotes.Controllers
{
    public class TaskPersonController : Controller
    {
        private readonly string _connectionType;
        private readonly string _connectionString;
        private readonly int _pageSize;

        private static readonly List<int> AllowedTaskRoleId = new List<int> { 1 };

        public TaskPersonController()
        {
            _connectionType = ConfigurationManager.AppSettings["ConnectionType"];
            _connectionString = ConfigurationManager.ConnectionStrings["WebStickyNotesData"].ConnectionString;
            _pageSize = int.Parse(ConfigurationManager.AppSettings["PageSize"]);
        }

        [HttpGet]
        [MustSignIn]
        public ActionResult Index(int? page)
        {
            var pageNumber = PagingHelper.GetPageNumber(page);

            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                var results = supplier.DataAccess.GetAllTaskPeople();

                var model = new TaskPersonIndexModel
                {
                    TotalRecords = results.Count,
                    CurrentPage = pageNumber,
                    PageSize = _pageSize,
                    PagingLink = string.Format("{0}?page={1}", Request.Url.AbsolutePath, "{0}"),
                    TaskPersons = PagingHelper.GetPageOfResults(results, _pageSize, pageNumber),
                    CurrentUser = currentUser
                };

                return View(model);
            }
        }

        [HttpGet]
        [MustSignIn]
        public ActionResult Detail(int id)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                var model = supplier.DataAccess.GetTaskPerson(id);

                return PartialView(model);
            }
        }

        [HttpGet]
        [MustSignIn]
        public ActionResult Add()
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                var model = new EditTaskPersonModel
                                {
                                    Message = new Message(),
                                    Person = new TaskPerson
                                        {
                                            TaskRoleId = 1
                                        },
                                    TaskProjects = FilteredDataHelper.GetFilteredTaskProjectsForUser(supplier.DataAccess, currentUser)
                                };

                PopulatePageLabels(model, supplier.DataAccess);

                return View("Edit", model);
            }
        }

        [HttpPost]
        [MustSignIn]
        public ActionResult Add(EditTaskPersonModel model)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                ValidateEditTaskPersonModel(model);

                if (ModelState.IsValid)
                {
					// Always MD5 the password on the database.
					model.Person.Password = EncryptionHelper.HashString(model.Person.Password);

                    var addSuccessModel = new AddSuccessModel
                                              {
                                                  Id = supplier.DataAccess.SaveTaskPerson(model.Person, model.SelectedProjects),
                                                  Action = "Edit",
                                                  Controller = "TaskPerson",
                                                  ViewItems = Labels.People,
                                                  ViewAction = "TaskPeople",
                                                  Message = new Message
                                                                {
                                                                    Class = "okay",
                                                                    Text = Labels.SavedOkay
                                                                }
                                              };

                    // Audit
                    AuditHelper.AuditAction(supplier.DataAccess, "Add", model.Person, currentUser.Id);

                    // ReSharper disable Asp.NotResolved
                    return View(addSuccessModel);
                    // ReSharper restore Asp.NotResolved
                }

                model.Message = new Message { Text = Labels.PleaseCorrectErrors, Class = "error" };
                model.TaskProjects = FilteredDataHelper.GetFilteredTaskProjectsForUser(supplier.DataAccess, currentUser);

                PopulatePageLabels(model, supplier.DataAccess);

                return View("Edit", model);
            }
        }

        [HttpGet]
        [MustSignIn]
        public ActionResult Edit(int id)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                IEnumerable<int> selectedProjects = supplier.DataAccess.GetTaskProjectsForPerson(id).Select(p => p.Id);

                var model = new EditTaskPersonModel
                                {
                                    Message = new Message(),
                                    Person = supplier.DataAccess.GetTaskPerson(id),
                                    TaskProjects = FilteredDataHelper.GetFilteredTaskProjectsForUser(supplier.DataAccess, currentUser),
                                    SelectedProjects = selectedProjects
                                };

                PopulatePageLabels(model, supplier.DataAccess);

                return View(model);
            }
        }

        [HttpPost]
        [MustSignIn]
        public ActionResult Edit(EditTaskPersonModel model)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                ValidateEditTaskPersonModel(model);

                if (ModelState.IsValid)
                {
                    // Always MD5 the password on the database.
                    model.Person.Password = EncryptionHelper.HashString(model.Person.Password);

                    supplier.DataAccess.SaveTaskPerson(model.Person, model.SelectedProjects);
                    model.Message = new Message { Text = Labels.SavedOkay, Class = "okay" };
                    model.TaskProjects = FilteredDataHelper.GetFilteredTaskProjectsForUser(supplier.DataAccess, currentUser);

                    // Audit
                    AuditHelper.AuditAction(supplier.DataAccess, "Edit", model.Person, currentUser.Id);

                    return RedirectToAction("Edit", new {id = model.Person.Id});
                }

                model.Message = new Message { Text = Labels.PleaseCorrectErrors, Class = "error" };

                PopulatePageLabels(model, supplier.DataAccess);

                return View(model);
            }
        }

        [HttpGet]
        [MustSignIn]
        public ActionResult Delete(int id)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                var model = new DeleteTaskPersonModel
                                {
                                    Person = supplier.DataAccess.GetTaskPerson(id),
                                    ShowButton = true,
                                    Message = new Message
                                    {
                                        Text = Labels.TextAreYouSureYouWantToDelete,
                                        Class = "error"
                                    }
                                };

                var taskCount = supplier.DataAccess.GetTasksByPerson(id).Count;

                if (taskCount > 0)
                {
                    model.ShowButton = false;
                    model.Message.Text = string.Format(Labels.TextCannotDelete, taskCount);
                    model.Message.Class = "error";
                }

                return View(model);
            }
        }

        [HttpPost]
        [MustSignIn]
        public ActionResult Delete(bool confirm, int id)
        {
            using (var supplier = new Supplier(_connectionType, _connectionString))
            {
                var currentUser = supplier.DataAccess.GetTaskPerson(SecurityHelper.GetSignedInUserId());
                if (!AllowedTaskRoleId.Contains(currentUser.TaskRoleId))
                {
                    return RedirectToAction("AccessDenied", "Home", new { address = HttpContext.Request.Url.AbsoluteUri });
                }

                var model = new DeleteTaskPersonModel
                {
                    Person = supplier.DataAccess.GetTaskPerson(id),
                    ShowButton = false,
                    Message = new Message
                    {
                        Text = Labels.DeletedOkay,
                        Class = "okay"
                    }
                };

                supplier.DataAccess.DeleteTaskPerson(id);

                // Audit
                AuditHelper.AuditAction(supplier.DataAccess, "Delete", model.Person, currentUser.Id);

                return View(model);
            }
        }

        private static void PopulatePageLabels(EditTaskPersonModel model, IWebStickyNotesDataAccess dataAccess)
        {
            model.TaskRoles = dataAccess.GetAllTaskRoles();
        }

        private void ValidateEditTaskPersonModel(EditTaskPersonModel model)
        {
            if (string.IsNullOrEmpty(model.Person.FirstName))
            {
                ModelState.AddModelError("Person.FirstName", Labels.PleaseEnterFirstName);
            }

            if (string.IsNullOrEmpty(model.Person.LastName))
            {
                ModelState.AddModelError("Person.LastName", Labels.PleaseEnterLastName);
            }

            if (string.IsNullOrEmpty(model.Person.Email))
            {
                ModelState.AddModelError("Person.Email", Labels.PleaseEnterEmail);
            }
        }
    }
}